
#include "ctc_error.h"
#include "ctc_at_diag.h"
#include "sys_usw_diag.h"


int32
ctc_at_diag_init(uint8 lchip, void* diag_init_cfg)
{
    uint8 lchip_start              = 0;
    uint8 lchip_end                = 0;
    ctc_diag_global_cfg_t   global_cfg;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_DIAG);
    LCHIP_CHECK(lchip);
    if (NULL == diag_init_cfg)
    {
        sal_memset(&global_cfg, 0, sizeof(ctc_diag_global_cfg_t));
        diag_init_cfg                 = &global_cfg;
    }

    CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, 1)
    {
        CTC_ERROR_RETURN(sys_usw_diag_init(lchip, diag_init_cfg));
    }
    return CTC_E_NONE;
}

int32
ctc_at_diag_deinit(uint8 lchip)
{
    uint8 lchip_start              = 0;
    uint8 lchip_end                = 0;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_DIAG);
    LCHIP_CHECK(lchip);

    CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, 1)
    {
        CTC_ERROR_RETURN(sys_usw_diag_deinit(lchip));
    }
    return CTC_E_NONE;
}

int32
ctc_at_diag_trigger_pkt_trace(uint8 lchip_id, ctc_diag_pkt_trace_t *p_trace)
{
    uint8 lchip = lchip_id;
    uint8 temp_lchip = 0;
    uint8 lchip_start = 0;
    uint8 lchip_end = 0;
    uint8 all_lchip = 1;
    uint16 pp_bmp = 0;
    uint8 pp_id = 0;
    uint8 lchip_map_num = 0;
    int32 ret = CTC_E_NONE;
    uint32 gport = 0;
    uint8 gchip_id = 0;
    FEATURE_SUPPORT_CHECK(CTC_FEATURE_DIAG);
    LCHIP_CHECK(lchip_id);
    CTC_PTR_VALID_CHECK(p_trace);

    pp_bmp = SYS_PP_BMP_MAPPING(p_trace->pp_bmp);
    switch (p_trace->watch_point)
    {
        case CTC_DIAG_TRACE_POINT_IPE_SCL:
        case CTC_DIAG_TRACE_POINT_EPE_ADJ:
            if (CTC_BMP_ISSET(p_trace->watch_key.key_mask_bmp, CTC_DIAG_WATCH_KEY_MASK_SRC_LPORT))
            {
                CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip_id, &gchip_id));
                gport = CTC_MAP_LPORT_TO_GPORT(gchip_id, p_trace->watch_key.src_lport);
                SYS_MAP_GPORT_TO_LCHIP1(gport, lchip);
                lchip_map_num++;
                all_lchip = 0;
            }
            
            if (CTC_BMP_ISSET(p_trace->watch_key.key_mask_bmp, CTC_DIAG_WATCH_KEY_MASK_CHANNEL))
            {
                SYS_MAP_CHANID_TO_PP_ID(lchip, 0,  p_trace->watch_key.channel, pp_id);
                if (lchip_map_num && lchip != SYS_PP_BASE(lchip) + pp_id)
                {
                    return CTC_E_PARAM_CONFLICT;
                }
                lchip = SYS_PP_BASE(lchip) + pp_id;
                lchip_map_num++;
                all_lchip = 0;
            }
            break;
        case CTC_DIAG_TRACE_POINT_TM_BS:
            if (CTC_BMP_ISSET(p_trace->watch_key.key_mask_bmp, CTC_DIAG_WATCH_KEY_MASK_SRC_GPORT))
            {
                SYS_MAP_GPORT_TO_LCHIP1(p_trace->watch_key.src_gport, lchip);
                lchip_map_num++;
                all_lchip = 0;
            }

            if (CTC_BMP_ISSET(p_trace->watch_key.key_mask_bmp, CTC_DIAG_WATCH_KEY_MASK_SRC_LPORT))
            {
                CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip_id, &gchip_id));
                gport = CTC_MAP_LPORT_TO_GPORT(gchip_id, p_trace->watch_key.src_lport);
                SYS_MAP_GPORT_TO_LCHIP1(gport, temp_lchip);
                if (lchip_map_num && lchip != temp_lchip)
                {
                    return CTC_E_PARAM_CONFLICT;
                }
                lchip = temp_lchip;
                lchip_map_num++;
                all_lchip = 0;
            }

            if (CTC_BMP_ISSET(p_trace->watch_key.key_mask_bmp, CTC_DIAG_WATCH_KEY_MASK_CHANNEL))
            {
                SYS_MAP_CHANID_TO_PP_ID(lchip, 0, p_trace->watch_key.channel, pp_id);
                temp_lchip = SYS_PP_BASE(lchip) + pp_id;
                if (lchip_map_num && lchip != temp_lchip)
                {
                    return CTC_E_PARAM_CONFLICT;
                }
                lchip = temp_lchip;
                lchip_map_num++;
                all_lchip = 0;
            }
            break;
        case CTC_DIAG_TRACE_POINT_TM_MET:
        case CTC_DIAG_TRACE_POINT_OAM_ADJ:
        case CTC_DIAG_TRACE_POINT_OAM_TX:
            break;
        case CTC_DIAG_TRACE_POINT_SC_OAM_RX:
        case CTC_DIAG_TRACE_POINT_SC_OAM_TX:
            return CTC_E_NOT_SUPPORT;
        default:
            break;
    }
    
    if (lchip_map_num)
    {
        lchip_start = lchip;
        lchip_end = lchip_start + 1;
    }

    CTC_ERROR_RETURN(sys_usw_diag_pkt_trace_key_check_and_clear_rslt(lchip, p_trace));

    CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, all_lchip)
    {
        if (!CTC_IS_BIT_SET(pp_bmp, lchip-lchip_start) && all_lchip)
        {
            continue;
        }
        CTC_AT_FOREACH_ERROR_RETURN(ret, sys_usw_diag_trigger_pkt_trace(lchip, p_trace));
    }

    return ret;
}

int32
ctc_at_diag_get_pkt_trace(uint8 lchip_id, ctc_diag_pkt_trace_result_t* p_rslt)
{
    uint8 lchip = lchip_id;
    uint8 i;
    uint8 lchip_start;
    uint8 lchip_end;
    uint8 temp_lchip = 0xff;
    uint8 pp_base = 0;
    FEATURE_SUPPORT_CHECK(CTC_FEATURE_DIAG);
    LCHIP_CHECK(lchip_id);

    lchip_start = SYS_PP_BASE(lchip);
    lchip_end = lchip_start + SYS_PP_NUM(lchip);
    if (CTC_DIAG_TRACE_POINT_SC_OAM_RX == p_rslt->watch_point || CTC_DIAG_TRACE_POINT_SC_OAM_TX == p_rslt->watch_point)
    {
        return CTC_E_NOT_SUPPORT;
    }

    for (i = CTC_DIAG_TRACE_POS_IPE; i < CTC_DIAG_TRACE_POS_MAX; i++)
    {
        if (CTC_DIAG_TRACE_POS_SC_OAM == i)
        {
            continue;
        }
        for (lchip = lchip_start; lchip < lchip_end; lchip++)
        {
            if (CTC_DIAG_TRACE_POS_OAM == i)
            {
                pp_base = sys_usw_vchip_get_core_pp_base(lchip);
                if (temp_lchip == pp_base)
                {
                    continue;
                }
                temp_lchip = pp_base;
            }
            CTC_ERROR_RETURN(sys_usw_diag_get_pkt_trace(lchip, p_rslt, i));
        }

    }
    return CTC_E_NONE;
}


int32
ctc_at_diag_get_drop_info(uint8 lchip_id, ctc_diag_drop_t* p_drop)
{
    uint8 lchip = lchip_id;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_DIAG);
    LCHIP_CHECK(lchip_id);
    CTC_ERROR_RETURN(sys_usw_diag_get_drop_info(lchip_id, p_drop));
    return CTC_E_NONE;
}


int32
ctc_at_diag_set_property(uint8 lchip_id, ctc_diag_property_t prop, void* p_value)
{
    uint8 lchip = lchip_id;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_DIAG);
    LCHIP_CHECK(lchip_id);
    CTC_ERROR_RETURN(sys_usw_diag_set_property(lchip_id, prop, p_value));
    return CTC_E_NONE;
}

int32
ctc_at_diag_get_property(uint8 lchip_id, ctc_diag_property_t prop, void* p_value)
{
    uint8 lchip = lchip_id;

    FEATURE_SUPPORT_CHECK(CTC_FEATURE_DIAG);
    LCHIP_CHECK(lchip_id);
    CTC_ERROR_RETURN(sys_usw_diag_get_property(lchip_id, prop, p_value));
    return CTC_E_NONE;
}

int32
ctc_at_diag_tbl_control(uint8 lchip_id, ctc_diag_tbl_t* p_para)
{
    uint8 lchip = lchip_id;
    FEATURE_SUPPORT_CHECK(CTC_FEATURE_DIAG);
    LCHIP_CHECK(lchip);
    CTC_ERROR_RETURN(sys_usw_diag_tbl_control(lchip, p_para));
    return CTC_E_NONE;
}

int32
ctc_at_diag_set_lb_distribution(uint8 lchip_id,ctc_diag_lb_dist_t* p_para)
{
    uint8 lchip = lchip_id;
    FEATURE_SUPPORT_CHECK(CTC_FEATURE_DIAG);
    LCHIP_CHECK(lchip);
    CTC_ERROR_RETURN(sys_usw_diag_set_lb_distribution(lchip, p_para));
    return CTC_E_NONE;
}

int32
ctc_at_diag_get_lb_distribution(uint8 lchip_id,ctc_diag_lb_dist_t* p_para)
{
    uint8 lchip = lchip_id;
    FEATURE_SUPPORT_CHECK(CTC_FEATURE_DIAG);
    LCHIP_CHECK(lchip);
    CTC_ERROR_RETURN(sys_usw_diag_get_lb_distribution(lchip, p_para));
    return CTC_E_NONE;
}

int32
ctc_at_diag_get_memory_usage(uint8 lchip_id,ctc_diag_mem_usage_t* p_para)
{
    uint8 lchip = lchip_id;
    
    FEATURE_SUPPORT_CHECK(CTC_FEATURE_DIAG);
    LCHIP_CHECK(lchip);
    CTC_MAX_VALUE_CHECK(p_para->pp_id, (SYS_PP_NUM(lchip)-1));
   
    CTC_ERROR_RETURN(sys_usw_diag_get_mem_usage((SYS_PP_BASE(lchip) + p_para->pp_id), p_para));
    return CTC_E_NONE;
}

int32
ctc_at_diag_mem_bist(uint8 lchip_id, ctc_diag_bist_mem_type_t mem_type, uint8* p_err_mem_id)
{
    uint8 lchip = lchip_id;
    uint8 lchip_start              = 0;
    uint8 lchip_end                = 0;
    FEATURE_SUPPORT_CHECK(CTC_FEATURE_DIAG);
    LCHIP_CHECK(lchip);
 
    CTC_AT_FOREACH_LCHIP(lchip_start, lchip_end, 1)
    {
      CTC_ERROR_RETURN(sys_usw_diag_mem_bist(lchip, mem_type, p_err_mem_id));
    }
    return CTC_E_NONE;
}

int32
ctc_at_diag_get_queue_depth(uint8 lchip_id, ctc_diag_queue_depth_t* p_queue)
{
    uint8 lchip = lchip_id;
    uint8 lchip_start              = 0;
    uint8 lchip_end                = 0;
    FEATURE_SUPPORT_CHECK(CTC_FEATURE_DIAG);
    LCHIP_CHECK(lchip);
	CTC_FOREACH_LCHIP(lchip_start, lchip_end, 1)
	{
    	CTC_ERROR_RETURN(sys_usw_diag_get_queue_depth(lchip, p_queue));
	}
    return CTC_E_NONE;
}

int32
ctc_at_diag_get_lb_hash(uint8 lchip_id, ctc_field_key_t* p_field_list, uint32 field_cnt, ctc_diag_lb_hash_t* p_rslt)
{
    uint8 lchip = lchip_id;
    uint8 lchip_start              = 0;
    uint8 lchip_end                = 0;
    FEATURE_SUPPORT_CHECK(CTC_FEATURE_DIAG);
    LCHIP_CHECK(lchip);
	CTC_FOREACH_LCHIP(lchip_start, lchip_end, 1)
	{
    	CTC_ERROR_RETURN(sys_usw_diag_get_lb_hash(lchip, p_field_list, field_cnt, p_rslt));
	}
    return CTC_E_NONE;
}
